package com.lx.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.lx.config.AliPayConfig;
import com.lx.entity.Order;
import com.lx.entity.OrderDetail;
import com.lx.entity.Product;
import com.lx.service.OrderService;
import com.lx.service.ProductService;
import com.lx.util.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;

/**
 * 2025/9/21 12:53
 * author: 向远洋
 */
@RequestMapping("/api")
@RestController // 添加这个注解
public class AliPayController {

    @Autowired
    private AliPayConfig aliPayConfig; // 改为注入你的 AliPayConfig
    @Autowired
    private OrderService orderService;
    @Autowired
    private ProductService productService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @PostMapping("/alipay/zf") // 修改路径避免冲突
    public void zf(@RequestBody Order order, HttpServletResponse response, HttpServletRequest request) throws AlipayApiException, IOException {
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(
                aliPayConfig.getGatewayUrl(),
                aliPayConfig.getApp_id(),
                aliPayConfig.getMerchant_private_key(),
                "json",
                aliPayConfig.getCharset(),
                aliPayConfig.getAlipay_public_key(),
                aliPayConfig.getSign_type()
        );

        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();

        //设置同步回调地址
        alipayRequest.setReturnUrl(aliPayConfig.getReturn_url());
        //设置异步回调地址
        alipayRequest.setNotifyUrl(aliPayConfig.getNotify_url());

        //商户订单号，商户网站订单系统中唯一订单号，必填
        String out_trade_no = order.getSerialNumber();
        //付款金额，必填
        String total_amount = order.getCost().toString();
        //订单名称，必填
        String subject = "易买网购物车订单商品";

        alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\","
                + "\"total_amount\":\"" + total_amount + "\","
                + "\"subject\":\"" + subject + "\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

        //请求
        String result = alipayClient.pageExecute(alipayRequest).getBody();

        response.setContentType("text/html");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write(result);
        response.getWriter().close();
    }

    @RequestMapping("/alipay/notify_url")
    public void notify_url(HttpServletRequest request, HttpServletResponse response) throws IOException, AlipayApiException {
        System.out.println("异步回调开始执行");
        //获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }

        boolean signVerified = AlipaySignature.rsaCheckV1(
                params,
                aliPayConfig.getAlipay_public_key(),
                aliPayConfig.getCharset(),
                aliPayConfig.getSign_type()
        );

        response.setContentType("text/html");
        response.setCharacterEncoding("UTF-8");
        PrintWriter out = response.getWriter();

        if (signVerified) {
            //商户订单号
            String out_trade_no = request.getParameter("out_trade_no");
            //支付宝交易号
            String trade_no = request.getParameter("trade_no");
            //交易状态
            String trade_status = request.getParameter("trade_status");

            if ("TRADE_FINISHED".equals(trade_status)) {
                System.out.println("交易关闭！");
            } else if ("TRADE_SUCCESS".equals(trade_status)) {
                //修改订单为已支付
                System.out.println(orderService.modifyOrderStatusBySerialNumber(out_trade_no, 1) ? "付款完成！" : "数据库修改订单失败");
            }

            out.println("success");
        } else {
            out.println("fail");
            System.out.println("验证失败");
        }
        out.close();
        System.out.println("异步回调执行完成");
    }

    @RequestMapping("/alipay/return_url")
    public void return_url(HttpServletRequest request, HttpServletResponse response) throws IOException, AlipayApiException {
        System.out.println("同步回调执行");
        //获取支付宝GET过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }

        boolean signVerified = AlipaySignature.rsaCheckV1(
                params,
                aliPayConfig.getAlipay_public_key(),
                aliPayConfig.getCharset(),
                aliPayConfig.getSign_type()
        );

        response.setContentType("text/html");
        response.setCharacterEncoding("UTF-8");
        PrintWriter out = response.getWriter();

        if (signVerified) {
            out.println("<h1>支付完成</h1>");
            String out_trade_no = request.getParameter("out_trade_no");
            String trade_no = request.getParameter("trade_no");
            String total_amount = request.getParameter("total_amount");

            stringRedisTemplate.opsForValue().set("tradeNo", trade_no);
            stringRedisTemplate.opsForValue().set("refundAmount", total_amount);
            out.println("支付宝交易号:" + trade_no + "<br/>商户订单号:" + out_trade_no + "<br/>付款金额:" + total_amount);
        } else {
            out.println("验签失败");
        }
        System.out.println("同步回调执行完成");
        out.close();
    }

    /**
     * @param params， 退款要求：serialNumber + orderId
     * @param res
     * @return
     *
     * @throws AlipayApiException
     * @throws IOException
     */
    @RequestMapping("/alipay/tk") //这里退款默认退货
    public Result tk(@RequestBody Map<String, Object> params, HttpServletResponse res) throws AlipayApiException, IOException {
        AlipayClient alipayClient = new DefaultAlipayClient(
                aliPayConfig.getGatewayUrl(),
                aliPayConfig.getApp_id(),
                aliPayConfig.getMerchant_private_key(),
                "json",
                aliPayConfig.getCharset(),
                aliPayConfig.getAlipay_public_key(),
                aliPayConfig.getSign_type()
        );

        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();

        //获取订单序列号 + 金额（金额不能为空）
        String serialNumber = params.get("serialNumber").toString();
        model.setOutTradeNo(serialNumber);
        model.setRefundAmount(params.get("cost").toString());
        request.setBizModel(model);

        res.setContentType("text/html");
        res.setCharacterEncoding("UTF-8");

        try {
            AlipayTradeRefundResponse response = alipayClient.execute(request);
            if (response.isSuccess()) {
                // 支付宝接口调用成功
                if ("10000".equals(response.getCode())) { // 必须校验业务码
                    System.out.println("退款成功，订单序列号：" + response.getOutTradeNo());
                    //修改订单状态 -> 已退款， 恢复商品
                    Integer orderId = Integer.parseInt(params.get("orderId").toString());
                    orderService.modifyOrderStatusById(orderId, 2);
                    List<OrderDetail> orderDetailList = orderService.getOrderDetailList(Collections.singletonList(orderId));
                    for (OrderDetail orderDetail : orderDetailList) {
                        //恢复es和数据库
                        Product p = productService.getProductById(orderDetail.getProductId());
                        p.setStock(p.getStock() + orderDetail.getQuantity());
                        productService.updateProduct(p); //同步es + 异步数据库
                    }

                    return Result.success(5200, "退款成功，订单序列号：" + response.getOutTradeNo());
                } else {
                    // 业务层面失败（如余额不足）
                    System.out.println("退款失败：" + response.getSubMsg());
                    return Result.error(5500, "退款失败：" + response.getSubMsg());
                }
            } else {
                // 网络或系统错误
                System.out.println("接口调用失败：" + response.getMsg());
                return Result.error(5500, "退款失败：" + response.getSubMsg());
            }
        } catch (Exception e) {
            return Result.error(5500, "退款异常：" + e.getMessage());
        }
    }
}